<script setup lang="ts">
import { ref, reactive, watch } from 'vue';
import { NModal, NCard, NForm, NFormItem, NInput, NSelect, NButton, NSpace, useMessage } from 'naive-ui';
import { executeQuery, exportQueryResult } from '@/service/api';
import { fetchDataSourceList } from '@/service/api';
import * as monaco from 'monaco-editor';

defineOptions({
  name: 'SqlEditorModal'
});

const emit = defineEmits<{
  success: [result: Api.DataPlatform.QueryResultDTO];
}>();

const message = useMessage();

const visible = ref(false);
const loading = ref(false);
const editorRef = ref<HTMLDivElement>();
let editorInstance: monaco.editor.IStandaloneCodeEditor | null = null;

const formModel = reactive<Api.DataPlatform.QueryExecuteDTO>({
  queryName: '',
  queryType: 'SQL',
  sqlContent: '',
  queryConfig: '',
  datasourceId: undefined as any,
  pageNum: 1,
  pageSize: 20,
  saveHistory: true,
  projectId: undefined
});

const datasourceOptions = ref<Array<{ label: string; value: number }>>([]);

// 打开模态框
function open() {
  visible.value = true;
  loadDataSources();
  
  // 初始化Monaco编辑器
  setTimeout(() => {
    if (editorRef.value && !editorInstance) {
      editorInstance = monaco.editor.create(editorRef.value, {
        value: formModel.sqlContent || 'SELECT * FROM table_name LIMIT 10',
        language: 'sql',
        theme: 'vs-dark',
        automaticLayout: true,
        minimap: { enabled: false },
        fontSize: 14,
        lineNumbers: 'on',
        scrollBeyondLastLine: false,
        wordWrap: 'on'
      });

      editorInstance.onDidChangeModelContent(() => {
        formModel.sqlContent = editorInstance?.getValue() || '';
      });
    }
  }, 100);
}

// 关闭模态框
function close() {
  visible.value = false;
  if (editorInstance) {
    editorInstance.dispose();
    editorInstance = null;
  }
  resetForm();
}

// 重置表单
function resetForm() {
  formModel.queryName = '';
  formModel.queryType = 'SQL';
  formModel.sqlContent = '';
  formModel.queryConfig = '';
  formModel.datasourceId = undefined as any;
  formModel.pageNum = 1;
  formModel.pageSize = 20;
  formModel.saveHistory = true;
}

// 加载数据源列表
async function loadDataSources() {
  try {
    const { data } = await fetchDataSourceList({ pageNum: 1, pageSize: 100 });
    if (data) {
      datasourceOptions.value = data.rows.map(item => ({
        label: item.name,
        value: item.id
      }));
    }
  } catch (error) {
    message.error('加载数据源失败');
  }
}

// 执行查询
async function handleExecute() {
  if (!formModel.datasourceId) {
    message.warning('请选择数据源');
    return;
  }
  if (!formModel.sqlContent) {
    message.warning('请输入SQL语句');
    return;
  }

  loading.value = true;
  try {
    const { data } = await executeQuery(formModel);
    if (data) {
      message.success('查询执行成功');
      emit('success', data);
      close();
    }
  } catch (error) {
    message.error('查询执行失败');
  } finally {
    loading.value = false;
  }
}

// 导出结果
async function handleExport(format: string) {
  if (!formModel.datasourceId) {
    message.warning('请选择数据源');
    return;
  }
  if (!formModel.sqlContent) {
    message.warning('请输入SQL语句');
    return;
  }

  loading.value = true;
  try {
    const blob = await exportQueryResult(formModel, format);
    const url = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = `query_result_${Date.now()}.${format.toLowerCase()}`;
    link.click();
    window.URL.revokeObjectURL(url);
    message.success('导出成功');
  } catch (error) {
    message.error('导出失败');
  } finally {
    loading.value = false;
  }
}

defineExpose({
  open
});
</script>

<template>
  <NModal v-model:show="visible" preset="card" title="SQL查询编辑器" class="w-1200px" :mask-closable="false">
    <NForm :model="formModel" label-placement="left" label-width="100px">
      <NFormItem label="查询名称" path="queryName">
        <NInput v-model:value="formModel.queryName" placeholder="请输入查询名称(可选)" />
      </NFormItem>

      <NFormItem label="数据源" path="datasourceId" required>
        <NSelect
          v-model:value="formModel.datasourceId"
          :options="datasourceOptions"
          placeholder="请选择数据源"
          filterable
        />
      </NFormItem>

      <NFormItem label="SQL语句" path="sqlContent" required>
        <div ref="editorRef" class="w-full h-400px border border-gray-300 rounded"></div>
      </NFormItem>

      <NFormItem label="分页设置">
        <NSpace>
          <NInput v-model:value="formModel.pageNum" placeholder="页码" class="w-100px" type="number" />
          <NInput v-model:value="formModel.pageSize" placeholder="每页大小" class="w-100px" type="number" />
        </NSpace>
      </NFormItem>
    </NForm>

    <template #footer>
      <NSpace justify="end">
        <NButton @click="close">取消</NButton>
        <NButton type="info" :loading="loading" @click="handleExport('CSV')">导出CSV</NButton>
        <NButton type="info" :loading="loading" @click="handleExport('JSON')">导出JSON</NButton>
        <NButton type="primary" :loading="loading" @click="handleExecute">执行查询</NButton>
      </NSpace>
    </template>
  </NModal>
</template>

<style scoped></style>
